Bug 1163254 - Add signedPkg to OriginAttributes. r=bholley
☠☠ backed out by d29141659999 ☠ ☠
authorhchang <hchang@mozilla.com>
Wed, 16 Sep 2015 19:42:00 +0200
changeset 297345 503eab197a2d2c67902f1bbece3e4712c8f38d18
parent 297344 fbf63ce1ba882223a2eda0644bbecc23e8670d6b
child 297346 47ccf6689101ff2031bbab999d50a6d4163cedaf
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1163254
milestone43.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 1163254 - Add signedPkg to OriginAttributes. r=bholley
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/tests/unit/test_origin.js
dom/base/StructuredCloneHelper.cpp
dom/cache/DBSchema.cpp
dom/webidl/ChromeUtils.webidl
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
@@ -57,16 +57,20 @@ OriginAttributes::CreateSuffix(nsACStrin
   }
 
   if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
     value.Truncate();
     value.AppendInt(mUserContextId);
     params->Set(NS_LITERAL_STRING("userContextId"), value);
   }
 
+  if (!mSignedPkg.IsEmpty()) {
+    params->Set(NS_LITERAL_STRING("signedPkg"), mSignedPkg);
+  }
+
   aStr.Truncate();
 
   params->Serialize(value);
   if (!value.IsEmpty()) {
     aStr.AppendLiteral("^");
     aStr.Append(NS_ConvertUTF16toUTF8(value));
   }
 
@@ -127,16 +131,22 @@ public:
       mOriginAttributes->mUserContextId = aValue.ToInteger(&rv);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return false;
       }
 
       return true;
     }
 
+    if (aName.EqualsLiteral("signedPkg")) {
+      MOZ_RELEASE_ASSERT(mOriginAttributes->mSignedPkg.IsEmpty());
+      mOriginAttributes->mSignedPkg.Assign(aValue);
+      return true;
+    }
+
     // No other attributes are supported.
     return false;
   }
 
 private:
   OriginAttributes* mOriginAttributes;
 };
 
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -31,17 +31,18 @@ public:
   explicit OriginAttributes(const OriginAttributesDictionary& aOther)
     : OriginAttributesDictionary(aOther) {}
 
   bool operator==(const OriginAttributes& aOther) const
   {
     return mAppId == aOther.mAppId &&
            mInBrowser == aOther.mInBrowser &&
            mAddonId == aOther.mAddonId &&
-           mUserContextId == aOther.mUserContextId;
+           mUserContextId == aOther.mUserContextId &&
+           mSignedPkg == aOther.mSignedPkg;
   }
   bool operator!=(const OriginAttributes& aOther) const
   {
     return !(*this == aOther);
   }
 
   // Serializes/Deserializes non-default values into the suffix format, i.e.
   // |!key1=value1&key2=value2|. If there are no non-default attributes, this
@@ -83,16 +84,20 @@ public:
     if (mAddonId.WasPassed() && mAddonId.Value() != aAttrs.mAddonId) {
       return false;
     }
 
     if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) {
       return false;
     }
 
+    if (mSignedPkg.WasPassed() && mSignedPkg.Value() != aAttrs.mSignedPkg) {
+      return false;
+    }
+
     return true;
   }
 };
 
 /*
  * Base class from which all nsIPrincipal implementations inherit. Use this for
  * default implementations and other commonalities between principal
  * implementations.
--- a/caps/tests/unit/test_origin.js
+++ b/caps/tests/unit/test_origin.js
@@ -117,22 +117,38 @@ function run_test() {
 
   // UserContext and App.
   var exampleOrg_userContextApp = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 24, userContextId: 42});
   var nullPrin_userContextApp = ssm.createNullPrincipal({appId: 24, userContextId: 42});
   checkOriginAttributes(exampleOrg_userContextApp, {appId: 24, userContextId: 42}, '^appId=24&userContextId=42');
   checkOriginAttributes(nullPrin_userContextApp, {appId: 24, userContextId: 42}, '^appId=24&userContextId=42');
   do_check_eq(exampleOrg_userContextApp.origin, 'http://example.org^appId=24&userContextId=42');
 
+  // Just signedPkg
+  var exampleOrg_signedPkg = ssm.createCodebasePrincipal(makeURI('http://example.org'), {signedPkg: 'whatever'});
+  checkOriginAttributes(exampleOrg_signedPkg, { signedPkg: 'id' }, '^signedPkg=whatever');
+  do_check_eq(exampleOrg_signedPkg.origin, 'http://example.org^signedPkg=whatever');
+
+  // signedPkg and browser
+  var exampleOrg_signedPkg_browser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {signedPkg: 'whatever', inBrowser: true});
+  checkOriginAttributes(exampleOrg_signedPkg_browser, { signedPkg: 'whatever', inBrowser: true }, '^inBrowser=1&signedPkg=whatever');
+  do_check_eq(exampleOrg_signedPkg_browser.origin, 'http://example.org^inBrowser=1&signedPkg=whatever');
+
+  // Just signedPkg (but different value from 'exampleOrg_signedPkg_app')
+  var exampleOrg_signedPkg_another = ssm.createCodebasePrincipal(makeURI('http://example.org'), {signedPkg: 'whatup'});
+
   // Check that all of the above are cross-origin.
   checkCrossOrigin(exampleOrg_app, exampleOrg);
   checkCrossOrigin(exampleOrg_app, nullPrin_app);
   checkCrossOrigin(exampleOrg_browser, exampleOrg_app);
   checkCrossOrigin(exampleOrg_browser, nullPrin_browser);
   checkCrossOrigin(exampleOrg_appBrowser, exampleOrg_app);
   checkCrossOrigin(exampleOrg_appBrowser, nullPrin_appBrowser);
   checkCrossOrigin(exampleOrg_appBrowser, exampleCom_appBrowser);
   checkCrossOrigin(exampleOrg_addon, exampleOrg);
   checkCrossOrigin(exampleOrg_userContext, exampleOrg);
   checkCrossOrigin(exampleOrg_userContextAddon, exampleOrg);
   checkCrossOrigin(exampleOrg_userContext, exampleOrg_userContextAddon);
   checkCrossOrigin(exampleOrg_userContext, exampleOrg_userContextApp);
+  checkCrossOrigin(exampleOrg_signedPkg, exampleOrg);
+  checkCrossOrigin(exampleOrg_signedPkg, exampleOrg_signedPkg_browser);
+  checkCrossOrigin(exampleOrg_signedPkg, exampleOrg_signedPkg_another);
 }
--- a/dom/base/StructuredCloneHelper.cpp
+++ b/dom/base/StructuredCloneHelper.cpp
@@ -427,24 +427,35 @@ StructuredCloneHelper::ReadFullySerializ
     } else {
       uint32_t appId = aIndex;
 
       uint32_t isInBrowserElement, specLength;
       if (!JS_ReadUint32Pair(aReader, &isInBrowserElement, &specLength)) {
         return nullptr;
       }
 
+      uint32_t signedPkgLength, dummy;
+      if (!JS_ReadUint32Pair(aReader, &signedPkgLength, &dummy)) {
+        return nullptr;
+      }
+
       nsAutoCString spec;
       spec.SetLength(specLength);
       if (!JS_ReadBytes(aReader, spec.BeginWriting(), specLength)) {
         return nullptr;
       }
 
+      nsAutoCString signedPkg;
+      spec.SetLength(signedPkgLength);
+      if (!JS_ReadBytes(aReader, signedPkg.BeginWriting(), signedPkgLength)) {
+        return nullptr;
+      }
+
       info = mozilla::ipc::ContentPrincipalInfo(appId, isInBrowserElement,
-                                                spec);
+                                                spec, signedPkg);
     }
 
     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;
     }
@@ -565,17 +576,19 @@ StructuredCloneHelper::WriteFullySeriali
       }
 
       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_WriteBytes(aWriter, cInfo.spec().get(), 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());
     }
   }
 
 #ifdef MOZ_NFC
   {
     MozNDEFRecord* ndefRecord;
     if (NS_SUCCEEDED(UNWRAP_OBJECT(MozNDEFRecord, aObj, ndefRecord))) {
       MOZ_ASSERT(NS_IsMainThread());
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -1903,18 +1903,19 @@ 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);
+      mozilla::ipc::ContentPrincipalInfo(attrs.mAppId, attrs.mInBrowser, originNoSuffix, signedPkg);
   }
 
   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/webidl/ChromeUtils.webidl
+++ b/dom/webidl/ChromeUtils.webidl
@@ -36,23 +36,23 @@ interface ChromeUtils : ThreadSafeChrome
  * OriginAttributes, the second is used for pattern-matching (i.e. does this
  * OriginAttributesDictionary match the non-empty attributes in this pattern).
  *
  * IMPORTANT: If you add any members here, you need to do the following:
  * (1) Add them to both dictionaries.
  * (2) Update the methods on mozilla::OriginAttributes, including equality,
  *     serialization, and deserialization.
  * (3) Update the methods on mozilla::OriginAttributesPattern, including matching.
- * (4) Bump the CIDs (_not_ IIDs) of all the principal implementations that
- *     use OriginAttributes in their nsISerializable implementations.
  */
 dictionary OriginAttributesDictionary {
   unsigned long appId = 0;
   unsigned long userContextId = 0;
   boolean inBrowser = false;
   DOMString addonId = "";
+  DOMString signedPkg = "";
 };
 dictionary OriginAttributesPatternDictionary {
   unsigned long appId;
   unsigned long userContextId;
   boolean inBrowser;
   DOMString addonId;
+  DOMString signedPkg;
 };
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -327,18 +327,19 @@ 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);
+      mozilla::ipc::ContentPrincipalInfo(attrs.mAppId, attrs.mInBrowser, line, signedPkg);
 
     GET_LINE(entry->scope());
     GET_LINE(entry->scriptSpec());
     GET_LINE(entry->currentWorkerURL());
 
     nsAutoCString cacheName;
     GET_LINE(cacheName);
     CopyUTF8toUTF16(cacheName, entry->activeCacheName());
--- a/dom/workers/test/gtest/TestReadWrite.cpp
+++ b/dom/workers/test/gtest/TestReadWrite.cpp
@@ -216,17 +216,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);
+      d->principal() = mozilla::ipc::ContentPrincipalInfo(i, i % 2, spec, EmptyCString());
       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();
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -77,16 +77,17 @@ PrincipalInfoToPrincipal(const Principal
         return nullptr;
       }
 
       if (info.appId() == 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);
         rv = principal ? NS_OK : NS_ERROR_FAILURE;
       }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
 
       return principal.forget();
@@ -197,16 +198,20 @@ 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) {
@@ -219,17 +224,17 @@ PrincipalToPrincipalInfo(nsIPrincipal* a
   }
 
   bool isInBrowserElement;
   rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  *aPrincipalInfo = ContentPrincipalInfo(appId, isInBrowserElement, spec);
+  *aPrincipalInfo = ContentPrincipalInfo(appId, isInBrowserElement, spec, signedPkg);
   return NS_OK;
 }
 
 nsresult
 LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
                        OptionalLoadInfoArgs* aOptionalLoadInfoArgs)
 {
   if (!aLoadInfo) {
--- a/ipc/glue/PBackgroundSharedTypes.ipdlh
+++ b/ipc/glue/PBackgroundSharedTypes.ipdlh
@@ -7,16 +7,17 @@ using struct mozilla::void_t from "ipc/I
 namespace mozilla {
 namespace ipc {
 
 struct ContentPrincipalInfo
 {
   uint32_t appId;
   bool isInBrowserElement;
   nsCString spec;
+  nsCString signedPkg;
 };
 
 struct SystemPrincipalInfo
 { };
 
 struct NullPrincipalInfo
 { };