Bug 916644 - Disable invoking WebIDL constructors without |new| unless you have the system principal. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Tue, 04 Mar 2014 10:05:08 -0800
changeset 171820 de377011ed9d1f9fcf02cd806c8dbf2fbab7e884
parent 171819 8eb71a24360bc987dfe7b3254dff93c6180f1105
child 171821 445ad0b80d92cde08f54a24ed290a815e913bb29
push id26340
push userryanvm@gmail.com
push dateTue, 04 Mar 2014 22:12:36 +0000
treeherdermozilla-central@e5b09585215f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs916644
milestone30.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 916644 - Disable invoking WebIDL constructors without |new| unless you have the system principal. r=bz
dom/bindings/Codegen.py
dom/tests/mochitest/bugs/test_bug370098.html
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1172,21 +1172,28 @@ class CGClassConstructor(CGAbstractStati
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
         preamble = """
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   JS::Rooted<JSObject*> obj(cx, &args.callee());
 """
+        # [ChromeOnly] interfaces may only be constructed by chrome.
+        # Additionally, we want to throw if a non-chrome caller does a bareword invocation of a
+        # constructor without |new|. We don't enforce this for chrome to avoid the addon compat
+        # fallout of making that change. See bug 916644.
         if isChromeOnly(self._ctor):
-            preamble += """  if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
+            mayInvokeCtor = "nsContentUtils::ThreadsafeIsCallerChrome()"
+        else:
+            mayInvokeCtor = "(args.isConstructing() || nsContentUtils::ThreadsafeIsCallerChrome())"
+        preamble += """  if (!%s) {
     return ThrowingConstructor(cx, argc, vp);
   }
-"""
+""" % mayInvokeCtor
         name = self._ctor.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
         callGenerator = CGMethodCall(nativeName, True, self.descriptor,
                                      self._ctor, isConstructor=True)
         return preamble + callGenerator.define();
 
 # Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod.
 class CGConstructNavigatorObjectHelper(CGAbstractStaticMethod):
--- a/dom/tests/mochitest/bugs/test_bug370098.html
+++ b/dom/tests/mochitest/bugs/test_bug370098.html
@@ -19,20 +19,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 370098 **/
 function test_constructor(dom_proto, shouldthrow) {
     var threw = false;
     try {
         window[dom_proto]();
     } catch (e) {
         threw = true;
     }
-    if (shouldthrow)
-      ok(threw, "Calling |" + dom_proto + "()| should throw");
-    else
-      todo(threw, "Calling |" + dom_proto + "()| should throw");
+    // XSLTProcessor is still on the old bindings.
+    if (dom_proto != 'XSLTProcessor')
+      ok(threw, "Calling |" + dom_proto + "()| should always throw");
 
     threw = false;
     try {
         new window[dom_proto]();
     } catch (e) {
         threw = true;
     }
     is(threw, shouldthrow, "Calling |new " + dom_proto + "()| should" + (shouldthrow ? " " : " not ") + "throw");