Bug 845862 - Transitively apply waivers for accessor descriptors. r=mrbkap
☠☠ backed out by e60919ded783 ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Tue, 02 Apr 2013 18:51:19 -0700
changeset 137977 6c6ab0e54917b4cb2f78a30bc11b44d9b967a460
parent 137976 63453515a870238be2a706eb6c4cac664d48d6c1
child 137978 97d16e7beb271701b2c8b647a80807dfc064a2a4
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs845862
milestone23.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 845862 - Transitively apply waivers for accessor descriptors. r=mrbkap
js/xpconnect/tests/unit/test_bug845862.js
js/xpconnect/tests/unit/xpcshell.ini
js/xpconnect/wrappers/WaiveXrayWrapper.cpp
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_bug845862.js
@@ -0,0 +1,13 @@
+const Cu = Components.utils;
+
+function run_test() {
+  // We rely on the crazy "wantXrays:false also causes values return from the
+  // sandbox to be waived" behavior, because it's the simplest way to get
+  // waivers out of the sandbox (which has no native objects). :-(
+  var sb = new Cu.Sandbox('http://www.example.com', {wantXrays: false});
+  Cu.evalInSandbox("this.foo = {}; Object.defineProperty(foo, 'bar', {get: function() {return {};}});", sb);
+  do_check_true(sb.foo != XPCNativeWrapper(sb.foo), "sb.foo is waived");
+  var desc = Object.getOwnPropertyDescriptor(sb.foo, 'bar');
+  var b = desc.get();
+  do_check_true(b != XPCNativeWrapper(b), "results from accessor descriptors are waived");
+}
--- a/js/xpconnect/tests/unit/xpcshell.ini
+++ b/js/xpconnect/tests/unit/xpcshell.ini
@@ -12,16 +12,17 @@ tail =
 [test_bug677864.js]
 [test_bug711404.js]
 [test_bug778409.js]
 [test_bug780370.js]
 [test_bug805807.js]
 [test_bug809652.js]
 [test_bug813901.js]
 [test_bug845201.js]
+[test_bug845862.js]
 [test_bug849730.js]
 [test_bug851895.js]
 [test_bug854558.js]
 [test_bug_442086.js]
 [test_file.js]
 [test_blob.js]
 [test_import.js]
 [test_import_fail.js]
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
@@ -10,40 +10,59 @@
 #include "XPCWrapper.h"
 
 #include "WaiveXrayWrapper.h"
 #include "AccessCheck.h"
 #include "WrapperFactory.h"
 
 namespace xpc {
 
+static bool
+WaiveAccessors(JSContext *cx, js::PropertyDescriptor *desc)
+{
+    if ((desc->attrs & JSPROP_GETTER) && desc->getter) {
+        JS::Value v = JS::ObjectValue(*JS_FUNC_TO_DATA_PTR(JSObject *, desc->getter));
+        if (!WrapperFactory::WaiveXrayAndWrap(cx, &v))
+            return false;
+        desc->getter = js::CastAsJSPropertyOp(&v.toObject());
+    }
+
+    if ((desc->attrs & JSPROP_SETTER) && desc->setter) {
+        JS::Value v = JS::ObjectValue(*JS_FUNC_TO_DATA_PTR(JSObject *, desc->setter));
+        if (!WrapperFactory::WaiveXrayAndWrap(cx, &v))
+            return false;
+        desc->setter = js::CastAsJSStrictPropertyOp(&v.toObject());
+    }
+    return true;
+}
+
 WaiveXrayWrapper::WaiveXrayWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags)
 {
 }
 
 WaiveXrayWrapper::~WaiveXrayWrapper()
 {
 }
 
 bool
 WaiveXrayWrapper::getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*>wrapper,
                                         JS::Handle<jsid> id, js::PropertyDescriptor *desc,
                                         unsigned flags)
 {
     return CrossCompartmentWrapper::getPropertyDescriptor(cx, wrapper, id, desc, flags) &&
-           WrapperFactory::WaiveXrayAndWrap(cx, &desc->value);
+           WrapperFactory::WaiveXrayAndWrap(cx, &desc->value) && WaiveAccessors(cx, desc);
 }
 
 bool
 WaiveXrayWrapper::getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
                                            JS::Handle<jsid> id, js::PropertyDescriptor *desc,
                                            unsigned flags)
 {
     return CrossCompartmentWrapper::getOwnPropertyDescriptor(cx, wrapper, id, desc, flags) &&
-           WrapperFactory::WaiveXrayAndWrap(cx, &desc->value);
+           WrapperFactory::WaiveXrayAndWrap(cx, &desc->value) && WaiveAccessors(cx, desc);
 }
 
 bool
 WaiveXrayWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper,
                       JS::Handle<JSObject*> receiver, JS::Handle<jsid> id,
                       JS::MutableHandle<JS::Value> vp)
 {
     return CrossCompartmentWrapper::get(cx, wrapper, receiver, id, vp) &&