Bug 930523 = createObjectIn should waive. r=bholley
authorGabor Krizsanits <gkrizsanits@mozilla.com>
Tue, 05 Nov 2013 08:02:07 +0100
changeset 153528 9b23ec089b2447f01ecb658131e213f0f885fa47
parent 153527 27ffaa0d3c03015657b5c9bdce843da0cb150c5d
child 153529 e30f630191b93194f4f94cf91bc05d8c5b7a3d5d
child 153545 5a6aa83529f03e62025e957a36a88c7c567a488b
push id35820
push usergkrizsanits@mozilla.com
push dateTue, 05 Nov 2013 07:07:21 +0000
treeherdermozilla-inbound@9b23ec089b24 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs930523
milestone28.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 930523 = createObjectIn should waive. r=bholley
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/tests/chrome/test_APIExposer.xul
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -336,17 +336,18 @@ interface nsIXPCComponents_Utils : nsISu
     [implicit_jscontext]
     jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname);
 
     /*
      * To be called from JS only.
      *
      * Returns an object created in |vobj|'s compartment.
      * If defineAs property on the options object is a non-null ID,
-     * the new object will be added to vobj as a property.
+     * the new object will be added to vobj as a property. Also, the
+     * returned new object is always automatically waived (see waiveXrays).
      */
     [implicit_jscontext]
     jsval createObjectIn(in jsval vobj, [optional] in jsval voptions);
 
     /*
      * To be called from JS only.
      *
      * Returns an array created in |vobj|'s compartment.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3020,34 +3020,35 @@ xpc::CreateObjectIn(JSContext *cx, Handl
         return false;
     }
 
     RootedObject scope(cx, js::CheckedUnwrap(&vobj.toObject()));
     if (!scope) {
         JS_ReportError(cx, "Permission denied to create object in the target scope");
         return false;
     }
+
     RootedObject obj(cx);
     {
         JSAutoCompartment ac(cx, scope);
         obj = JS_NewObject(cx, nullptr, nullptr, scope);
         if (!obj)
             return false;
 
         if (!JSID_IS_VOID(options.defineAs) &&
             !JS_DefinePropertyById(cx, scope, options.defineAs, ObjectValue(*obj),
-                                       JS_PropertyStub, JS_StrictPropertyStub,
-                                       JSPROP_ENUMERATE))
+                                   JS_PropertyStub, JS_StrictPropertyStub,
+                                   JSPROP_ENUMERATE))
             return false;
     }
 
-    if (!JS_WrapObject(cx, &obj))
+    rval.setObject(*obj);
+    if (!WrapperFactory::WaiveXrayAndWrap(cx, rval))
         return false;
 
-    rval.setObject(*obj);
     return true;
 }
 
 /* jsval evalInWindow(in string source, in jsval window); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::EvalInWindow(const nsAString &source, const Value &window,
                                     JSContext *cx, Value *rval)
 {
--- a/js/xpconnect/tests/chrome/test_APIExposer.xul
+++ b/js/xpconnect/tests/chrome/test_APIExposer.xul
@@ -21,17 +21,18 @@ https://bugzilla.mozilla.org/show_bug.cg
       const Cu = Components.utils;
 
       var sandbox = new Cu.Sandbox("about:blank");
       sandbox.ok = ok;
       sandbox.is = is;
       Cu.evalInSandbox("Object.defineProperty(Object.prototype, 'getProp', { get: function() { throw 'FAIL: called getter' }, set: function() { throw 'FAIL: called setter'; } })", sandbox);
 
       var obj = Cu.createObjectIn(sandbox);
-      is(Object.getPrototypeOf(obj), Cu.evalInSandbox("Object.prototype", sandbox),
+      is(obj, Cu.waiveXrays(obj), "createObjectIn waives");
+      is(Object.getPrototypeOf(obj), Cu.waiveXrays(Cu.evalInSandbox("Object.prototype", sandbox)),
          "Object is a sandbox object");
 
       function genPropDesc(value) {
           return { enumerable: true, configurable: true, writable: true,
                    value: value };
       }
       const props = {
           'getProp': genPropDesc(function() { ok(true, "called prop that shadowed a getter"); }),