Bug 1179557 - Add userContextId to originAttributes with tests. r=bholley, r=tanvi
authorSteven Englehardt <senglehardt@mozilla.com>
Tue, 28 Jul 2015 17:32:00 -0400
changeset 255704 993a36e7e0b3accaf70fa8c317251484eff273a4
parent 255703 c4105b808a54a0d979baa6da3913ab4169cdc520
child 255705 7f05504085b13468de1aefad6178f3f566fb9da1
push id14361
push userkwierso@gmail.com
push dateSat, 01 Aug 2015 00:15:48 +0000
treeherderfx-team@466ad45c6831 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley, tanvi
bugs1179557
milestone42.0a1
Bug 1179557 - Add userContextId to originAttributes with tests. r=bholley, r=tanvi
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/nsIScriptSecurityManager.idl
caps/nsNullPrincipal.h
caps/nsPrincipal.h
caps/tests/unit/test_origin.js
dom/webidl/ChromeUtils.webidl
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -42,16 +42,22 @@ OriginAttributes::CreateSuffix(nsACStrin
   if (mInBrowser) {
     params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
   }
 
   if (!mAddonId.IsEmpty()) {
     params->Set(NS_LITERAL_STRING("addonId"), mAddonId);
   }
 
+  if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
+    value.Truncate();
+    value.AppendInt(mUserContextId);
+    params->Set(NS_LITERAL_STRING("userContextId"), value);
+  }
+
   aStr.Truncate();
 
   params->Serialize(value);
   if (!value.IsEmpty()) {
     aStr.AppendLiteral("^");
     aStr.Append(NS_ConvertUTF16toUTF8(value));
   }
 }
@@ -95,16 +101,26 @@ public:
     }
 
     if (aName.EqualsLiteral("addonId")) {
       MOZ_RELEASE_ASSERT(mOriginAttributes->mAddonId.IsEmpty());
       mOriginAttributes->mAddonId.Assign(aValue);
       return true;
     }
 
+    if (aName.EqualsLiteral("userContextId")) {
+      nsresult rv;
+      mOriginAttributes->mUserContextId = aValue.ToInteger(&rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return false;
+      }
+
+      return true;
+    }
+
     // No other attributes are supported.
     return false;
   }
 
 private:
   OriginAttributes* mOriginAttributes;
 };
 
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -30,17 +30,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;
+           mAddonId == aOther.mAddonId &&
+           mUserContextId == aOther.mUserContextId;
   }
   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
@@ -78,16 +79,20 @@ public:
     if (mInBrowser.WasPassed() && mInBrowser.Value() != aAttrs.mInBrowser) {
       return false;
     }
 
     if (mAddonId.WasPassed() && mAddonId.Value() != aAttrs.mAddonId) {
       return false;
     }
 
+    if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) {
+      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/nsIScriptSecurityManager.idl
+++ b/caps/nsIScriptSecurityManager.idl
@@ -21,17 +21,17 @@ class DomainPolicyClone;
 }
 }
 %}
 
 [ptr] native JSContextPtr(JSContext);
 [ptr] native JSObjectPtr(JSObject);
 [ptr] native DomainPolicyClonePtr(mozilla::dom::DomainPolicyClone);
 
-[scriptable, uuid(50418f5c-b0d8-42c3-ba5d-efffb6927e1c)]
+[scriptable, uuid(9a8f0b70-6b9f-4e19-8885-7cfe24f4a42d)]
 interface nsIScriptSecurityManager : nsISupports
 {
     /**
      * For each of these hooks returning NS_OK means 'let the action continue'.
      * Returning an error code means 'veto the action'. XPConnect will return
      * false to the js engine if the action is vetoed. The implementor of this
      * interface is responsible for setting a JS exception into the JSContext
      * if that is appropriate.
@@ -250,16 +250,18 @@ interface nsIScriptSecurityManager : nsI
       return isSystem;
     }
 %}
 
     const unsigned long NO_APP_ID = 0;
     const unsigned long UNKNOWN_APP_ID = 4294967295; // UINT32_MAX
     const unsigned long SAFEBROWSING_APP_ID = 4294967294; // UINT32_MAX - 1
 
+    const unsigned long DEFAULT_USER_CONTEXT_ID = 0;
+
     /**
      * Returns the jar prefix for the app.
      * appId can be NO_APP_ID or a valid app id. appId should not be
      * UNKNOWN_APP_ID.
      * inMozBrowser has to be true if the app is inside a mozbrowser iframe.
      */
     AUTF8String getJarPrefix(in unsigned long appId, in boolean inMozBrowser);
 
--- a/caps/nsNullPrincipal.h
+++ b/caps/nsNullPrincipal.h
@@ -18,18 +18,18 @@
 #include "nsCOMPtr.h"
 #include "nsIContentSecurityPolicy.h"
 
 #include "mozilla/BasePrincipal.h"
 
 class nsIURI;
 
 #define NS_NULLPRINCIPAL_CID \
-{ 0x34a19ab6, 0xca47, 0x4098, \
-  { 0xa7, 0xb8, 0x4a, 0xfc, 0xdd, 0xcd, 0x8f, 0x88 } }
+{ 0xbd066e5f, 0x146f, 0x4472, \
+  { 0x83, 0x31, 0x7b, 0xfd, 0x05, 0xb1, 0xed, 0x90 } }
 #define NS_NULLPRINCIPAL_CONTRACTID "@mozilla.org/nullprincipal;1"
 
 #define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
 
 class nsNullPrincipal final : public mozilla::BasePrincipal
 {
 public:
   // This should only be used by deserialization, and the factory constructor.
--- a/caps/nsPrincipal.h
+++ b/caps/nsPrincipal.h
@@ -107,17 +107,17 @@ protected:
   bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
 
 private:
   nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
 };
 
 #define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
 #define NS_PRINCIPAL_CID \
-{ 0xb02c3023, 0x5b37, 0x472a, \
-  { 0xa2, 0xcd, 0x35, 0xaa, 0x5e, 0xe2, 0xa8, 0x19 } }
+{ 0x653e0e4d, 0x3ee4, 0x45fa, \
+  { 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
 
 #define NS_EXPANDEDPRINCIPAL_CONTRACTID "@mozilla.org/expandedprincipal;1"
 #define NS_EXPANDEDPRINCIPAL_CID \
 { 0xe8ee88b0, 0x5571, 0x4086, \
   { 0xa4, 0x5b, 0x39, 0xa7, 0x16, 0x90, 0x6b, 0xdb } }
 
 #endif // nsPrincipal_h__
--- a/caps/tests/unit/test_origin.js
+++ b/caps/tests/unit/test_origin.js
@@ -92,18 +92,41 @@ function run_test() {
   var exampleOrg_addon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy'});
   checkOriginAttributes(exampleOrg_addon, { addonId: "dummy" }, '^addonId=dummy');
   do_check_eq(exampleOrg_addon.origin, 'http://example.org^addonId=dummy');
 
   // Make sure that we refuse to create .origin for principals with UNKNOWN_APP_ID.
   var simplePrin = ssm.getSimpleCodebasePrincipal(makeURI('http://example.com'));
   try { simplePrin.origin; do_check_true(false); } catch (e) { do_check_true(true); }
 
+  // Just userContext.
+  var exampleOrg_userContext = ssm.createCodebasePrincipal(makeURI('http://example.org'), {userContextId: 42});
+  checkOriginAttributes(exampleOrg_userContext, { userContextId: 42 }, '^userContextId=42');
+  do_check_eq(exampleOrg_userContext.origin, 'http://example.org^userContextId=42');
+
+  // UserContext and Addon.
+  var exampleOrg_userContextAddon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy', userContextId: 42});
+  var nullPrin_userContextAddon = ssm.createNullPrincipal({addonId: 'dummy', userContextId: 42});
+  checkOriginAttributes(exampleOrg_userContextAddon, {addonId: 'dummy', userContextId: 42}, '^addonId=dummy&userContextId=42');
+  checkOriginAttributes(nullPrin_userContextAddon, {addonId: 'dummy', userContextId: 42}, '^addonId=dummy&userContextId=42');
+  do_check_eq(exampleOrg_userContextAddon.origin, 'http://example.org^addonId=dummy&userContextId=42');
+
+  // 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');
+
   // 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);
 }
--- a/dom/webidl/ChromeUtils.webidl
+++ b/dom/webidl/ChromeUtils.webidl
@@ -41,16 +41,18 @@ interface ChromeUtils : ThreadSafeChrome
  * (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 = "";
 };
 dictionary OriginAttributesPatternDictionary {
   unsigned long appId;
+  unsigned long userContextId;
   boolean inBrowser;
   DOMString addonId;
 };