Bug 1424474 part 2. Add a way to request only non-system subject principals in webidl bindings. r=mystor
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 20 Dec 2017 17:43:18 -0500
changeset 448974 d3f2ca3a3efeb6771fcbdb24d0d4cc30b63038b3
parent 448973 beb46b2f38d48591d907d5823b95c492fa36f89a
child 448975 7401a6e3f5edcc0f350c0370aadc2597eff6fb20
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1424474
milestone59.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 1424474 part 2. Add a way to request only non-system subject principals in webidl bindings. r=mystor MozReview-Commit-ID: 8ObneI0DoH5
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestExampleGen.webidl
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7410,41 +7410,63 @@ class CGCallGenerator(CGThing):
         elif result is not None:
             assert resultOutParam is None
             call = CGWrapper(call, pre=resultVar + " = ")
 
         call = CGWrapper(call, post=";\n")
         self.cgRoot.append(call)
 
         if needsSubjectPrincipal:
-            getPrincipal = dedent(
+            needsNonSystemPrincipal = (
+                "needsNonSystemSubjectPrincipal" in extendedAttributes)
+            if needsNonSystemPrincipal:
+                checkPrincipal = dedent(
+                    """
+                    if (nsContentUtils::IsSystemPrincipal(principal)) {
+                      principal = nullptr;
+                    }
+                    """)
+            else:
+                checkPrincipal = ""
+
+            getPrincipal = fill(
                 """
                 JSCompartment* compartment = js::GetContextCompartment(cx);
                 MOZ_ASSERT(compartment);
                 JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
-                """)
+                nsIPrincipal* principal = nsJSPrincipals::get(principals);
+                ${checkPrincipal}
+                """,
+                checkPrincipal=checkPrincipal)
 
             if descriptor.interface.isExposedInAnyWorker():
                 self.cgRoot.prepend(CGGeneric(fill(
                     """
                     Maybe<nsIPrincipal*> subjectPrincipal;
                     if (NS_IsMainThread()) {
                       $*{getPrincipal}
-                      subjectPrincipal.emplace(nsJSPrincipals::get(principals));
+                      subjectPrincipal.emplace(principal);
                     }
                     """,
                     getPrincipal=getPrincipal)))
             else:
+                if needsNonSystemPrincipal:
+                    principalType = "nsIPrincipal*";
+                else:
+                    principalType = "NonNull<nsIPrincipal>"
+
                 self.cgRoot.prepend(CGGeneric(fill(
                     """
-                    $*{getPrincipal}
-                    // Initializing a nonnull is pretty darn annoying...
-                    NonNull<nsIPrincipal> subjectPrincipal;
-                    subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
+                    ${principalType} subjectPrincipal;
+                    {
+                      $*{getPrincipal}
+                      subjectPrincipal = principal;
+                    }
                     """,
+                    principalType=principalType,
                     getPrincipal=getPrincipal)))
 
         if isFallible or canOOM:
             if isFallible:
                 reporterClass = "binding_detail::FastErrorResult"
             else:
                 reporterClass = "binding_danger::OOMReporterInstantiator"
             self.cgRoot.prepend(CGGeneric("%s rv;\n" % reporterClass))
@@ -14275,18 +14297,28 @@ class CGBindingRoot(CGThing):
 
         def dictionaryHasChromeOnly(dictionary):
             while dictionary:
                 if (any(isChromeOnly(m) for m in dictionary.members)):
                     return True
                 dictionary = dictionary.parent
             return False
 
+        def needsNonSystemPrincipal(member):
+            return (
+                member.getExtendedAttribute("NeedsSubjectPrincipal") == ["NonSystem"] or
+                member.getExtendedAttribute("SetterNeedsSubjectPrincipal") == ["NonSystem"] or
+                member.getExtendedAttribute("GetterNeedsSubjectPrincipal") == ["NonSystem"])
+
+        def descriptorNeedsNonSystemPrincipal(d):
+            return any(needsNonSystemPrincipal(m) for m in d.interface.members)
+
         bindingHeaders["nsContentUtils.h"] = (
             any(descriptorHasChromeOnly(d) for d in descriptors) or
+            any(descriptorNeedsNonSystemPrincipal(d) for d in descriptors) or
             any(dictionaryHasChromeOnly(d) for d in dictionaries))
         hasNonEmptyDictionaries = any(
             len(dict.members) > 0 for dict in dictionaries)
         callbacks = config.getCallbacks(webIDLFile)
         callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                                     isCallback=True)
         jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
                                               isJSImplemented=True)
@@ -14695,16 +14727,18 @@ class CGNativeMember(ClassMethod):
         elif returnType.isObject() or returnType.isSpiderMonkeyInterface():
             args.append(Argument("JS::MutableHandle<JSObject*>", "aRetVal"))
 
         # And the nsIPrincipal
         if 'needsSubjectPrincipal' in self.extendedAttrs:
             # Cheat and assume self.descriptorProvider is a descriptor
             if self.descriptorProvider.interface.isExposedInAnyWorker():
                 args.append(Argument("Maybe<nsIPrincipal*>", "aSubjectPrincipal"))
+            elif 'needsNonSystemSubjectPrincipal' in self.extendedAttrs:
+                args.append(Argument("nsIPrincipal*", "aPrincipal"))
             else:
                 args.append(Argument("nsIPrincipal&", "aPrincipal"))
         # And the caller type, if desired.
         if needsCallerType(self.member):
             args.append(Argument("CallerType", "aCallerType"))
         # And the ErrorResult or OOMReporter
         if 'infallible' not in self.extendedAttrs:
             # Use aRv so it won't conflict with local vars named "rv"
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -609,19 +609,26 @@ class Descriptor(DescriptorProvider):
                 attrs.append("infallible")
 
         def maybeAppendCanOOMToAttrs(attrs, canOOM):
             ensureValidCanOOMExtendedAttribute(canOOM)
             if canOOM is not None:
                 attrs.append("canOOM")
 
         def maybeAppendNeedsSubjectPrincipalToAttrs(attrs, needsSubjectPrincipal):
-            ensureValidNeedsSubjectPrincipalExtendedAttribute(needsSubjectPrincipal)
+            if (needsSubjectPrincipal is not None and
+                needsSubjectPrincipal is not True and
+                needsSubjectPrincipal != ["NonSystem"]):
+                raise TypeError("Unknown value for 'NeedsSubjectPrincipal': %s" %
+                                needsSubjectPrincipal[0])
+
             if needsSubjectPrincipal is not None:
                 attrs.append("needsSubjectPrincipal")
+                if needsSubjectPrincipal == ["NonSystem"]:
+                    attrs.append("needsNonSystemSubjectPrincipal")
 
         name = member.identifier.name
         throws = self.interface.isJSImplemented() or member.getExtendedAttribute("Throws")
         canOOM = member.getExtendedAttribute("CanOOM")
         needsSubjectPrincipal = member.getExtendedAttribute("NeedsSubjectPrincipal")
         if member.isMethod():
             # JSObject-returning [NewObject] methods must be fallible,
             # since they have to (fallibly) allocate the new JSObject.
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -966,16 +966,19 @@ public:
   bool CanOOMSetterAttr() const;
   void SetCanOOMSetterAttr(bool arg, OOMReporter& aRv);
   void NeedsSubjectPrincipalMethod(nsIPrincipal&);
   bool NeedsSubjectPrincipalAttr(nsIPrincipal&);
   void SetNeedsSubjectPrincipalAttr(bool, nsIPrincipal&);
   void NeedsCallerTypeMethod(CallerType);
   bool NeedsCallerTypeAttr(CallerType);
   void SetNeedsCallerTypeAttr(bool, CallerType);
+  void NeedsNonSystemSubjectPrincipalMethod(nsIPrincipal*);
+  bool NeedsNonSystemSubjectPrincipalAttr(nsIPrincipal*);
+  void SetNeedsNonSystemSubjectPrincipalAttr(bool, nsIPrincipal*);
   void CeReactionsMethod();
   void CeReactionsMethodOverload();
   void CeReactionsMethodOverload(const nsAString&);
   bool CeReactionsAttr() const;
   void SetCeReactionsAttr(bool);
   int16_t LegacyCall(const JS::Value&, uint32_t, TestInterface&);
   void PassArgsWithDefaults(JSContext*, const Optional<int32_t>&,
                             TestInterface*, const Dict&, double,
@@ -1461,16 +1464,19 @@ public:
   nsISupports* GetParentObject();
 
   void NeedsSubjectPrincipalMethod(Maybe<nsIPrincipal*>);
   bool NeedsSubjectPrincipalAttr(Maybe<nsIPrincipal*>);
   void SetNeedsSubjectPrincipalAttr(bool, Maybe<nsIPrincipal*>);
   void NeedsCallerTypeMethod(CallerType);
   bool NeedsCallerTypeAttr(CallerType);
   void SetNeedsCallerTypeAttr(bool, CallerType);
+  void NeedsNonSystemSubjectPrincipalMethod(Maybe<nsIPrincipal*>);
+  bool NeedsNonSystemSubjectPrincipalAttr(Maybe<nsIPrincipal*>);
+  void SetNeedsNonSystemSubjectPrincipalAttr(bool, Maybe<nsIPrincipal*>);
 };
 
 class TestHTMLConstructorInterface : public nsGenericHTMLElement
 {
 public:
   virtual nsISupports* GetParentObject();
 };
 
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -952,16 +952,18 @@ interface TestInterface {
   [CanOOM] void canOOMMethod();
   [CanOOM] attribute boolean canOOMAttr;
   [GetterCanOOM] attribute boolean canOOMGetterAttr;
   [SetterCanOOM] attribute boolean canOOMSetterAttr;
   [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
   [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
   [NeedsCallerType] void needsCallerTypeMethod();
   [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+  [NeedsSubjectPrincipal=NonSystem] void needsNonSystemSubjectPrincipalMethod();
+  [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
   [CEReactions] void ceReactionsMethod();
   [CEReactions] void ceReactionsMethodOverload();
   [CEReactions] void ceReactionsMethodOverload(DOMString bar);
   [CEReactions] attribute boolean ceReactionsAttr;
   legacycaller short(unsigned long arg1, TestInterface arg2);
   void passArgsWithDefaults(optional long arg1,
                             optional TestInterface? arg2 = null,
                             optional Dict arg3, optional double arg4 = 5.0,
@@ -1298,16 +1300,18 @@ interface TestSecureContextInterface {
 };
 
 [Exposed=(Window,Worker)]
 interface TestWorkerExposedInterface {
   [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
   [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
   [NeedsCallerType] void needsCallerTypeMethod();
   [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+  [NeedsSubjectPrincipal=NonSystem] void needsNonSystemSubjectPrincipalMethod();
+  [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
 };
 
 [HTMLConstructor]
 interface TestHTMLConstructorInterface {
 };
 
 interface TestCEReactionsInterface {
   [CEReactions] setter void (unsigned long index, long item);
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -778,16 +778,18 @@ interface TestExampleInterface {
   [GetterThrows] attribute boolean throwingGetterAttr;
   [SetterThrows] attribute boolean throwingSetterAttr;
   [CanOOM] void canOOMMethod();
   [CanOOM] attribute boolean canOOMAttr;
   [GetterCanOOM] attribute boolean canOOMGetterAttr;
   [SetterCanOOM] attribute boolean canOOMSetterAttr;
   [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
   [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
+  [NeedsSubjectPrincipal=NonSystem] void needsNonSystemSubjectPrincipalMethod();
+  [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
   [NeedsCallerType] void needsCallerTypeMethod();
   [NeedsCallerType] attribute boolean needsCallerTypeAttr;
   [CEReactions] void ceReactionsMethod();
   [CEReactions] void ceReactionsMethodOverload();
   [CEReactions] void ceReactionsMethodOverload(DOMString bar);
   [CEReactions] attribute boolean ceReactionsAttr;
   legacycaller short(unsigned long arg1, TestInterface arg2);
   void passArgsWithDefaults(optional long arg1,
@@ -828,9 +830,11 @@ interface TestExampleProxyInterface {
 };
 
 [Exposed=(Window,Worker)]
 interface TestExampleWorkerInterface {
   [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
   [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
   [NeedsCallerType] void needsCallerTypeMethod();
   [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+  [NeedsSubjectPrincipal=NonSystem] void needsNonSystemSubjectPrincipalMethod();
+  [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
 };