Bug 800410 - Debugger.Object.prototype.defineProperty needs to check that getters/setters are actually callable objects. r=jimb.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 03 Dec 2012 14:51:59 -0600
changeset 114930 d675239f3ca7
parent 114929 b7fd23ced4ee
child 114931 3b2331322084
push id23949
push userryanvm@gmail.com
push dateWed, 05 Dec 2012 01:17:54 +0000
treeherdermozilla-central@96343524e1fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs800410
milestone20.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 800410 - Debugger.Object.prototype.defineProperty needs to check that getters/setters are actually callable objects. r=jimb.
js/src/jit-test/tests/debug/Object-defineProperties-02.js
js/src/jit-test/tests/debug/Object-defineProperty-13.js
js/src/vm/Debugger.cpp
--- a/js/src/jit-test/tests/debug/Object-defineProperties-02.js
+++ b/js/src/jit-test/tests/debug/Object-defineProperties-02.js
@@ -25,8 +25,9 @@ function test(objexpr, descs) {
 
     assertEq(Object.getPrototypeOf(exca), Object.getPrototypeOf(excb));
     assertEq(exca.message, excb.message);
     assertEq(typeof exca.fileName, "string");
     assertEq(typeof exca.stack, "string");
 }
 
 test("Object.create(null, {p: {value: 1}})", {p: {value: 2}});
+test("({})", {x: {get: 'bad'}});
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-defineProperty-13.js
@@ -0,0 +1,16 @@
+// defineProperty throws if a getter or setter is neither undefined nor callable.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+
+for (let v of [null, false, 'bad', 0, 2.76, {}]) {
+    assertThrowsInstanceOf(function () {
+        gw.defineProperty("p", {configurable: true, get: v});
+    }, TypeError);
+    assertThrowsInstanceOf(function () {
+        gw.defineProperty("p", {configurable: true, set: v});
+    }, TypeError);
+}
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4141,16 +4141,18 @@ DebuggerObject_defineProperty(JSContext 
     PropDesc *desc = descs.append();
     if (!desc || !desc->initialize(cx, descval, false))
         return false;
     desc->clearPd();
 
     PropDesc *unwrappedDesc = descs.append();
     if (!unwrappedDesc || !desc->unwrapDebuggerObjectsInto(cx, dbg, obj, unwrappedDesc))
         return false;
+    if (!unwrappedDesc->checkGetter(cx) || !unwrappedDesc->checkSetter(cx))
+        return false;
 
     {
         PropDesc *rewrappedDesc = descs.append();
         if (!rewrappedDesc)
             return false;
         RootedId wrappedId(cx);
 
         Maybe<AutoCompartment> ac;
@@ -4186,16 +4188,18 @@ DebuggerObject_defineProperties(JSContex
     size_t n = ids.length();
 
     AutoPropDescArrayRooter unwrappedDescs(cx);
     for (size_t i = 0; i < n; i++) {
         if (!unwrappedDescs.append())
             return false;
         if (!descs[i].unwrapDebuggerObjectsInto(cx, dbg, obj, &unwrappedDescs[i]))
             return false;
+        if (!unwrappedDescs[i].checkGetter(cx) || !unwrappedDescs[i].checkSetter(cx))
+            return false;
     }
 
     {
         AutoIdVector rewrappedIds(cx);
         AutoPropDescArrayRooter rewrappedDescs(cx);
 
         Maybe<AutoCompartment> ac;
         ac.construct(cx, obj);