Bug 1107443. Make WindowProxy throw if you attempt to explicitly define a non-configurable property. r=peterv

This commit is contained in:
Boris Zbarsky 2015-07-23 11:51:09 -04:00
parent 31d2ce9ce4
commit 22d92d4edb
3 changed files with 28 additions and 4 deletions

View File

@ -759,6 +759,9 @@ nsOuterWindowProxy::getOwnPropertyDescriptor(JSContext* cx,
}
// else fall through to js::Wrapper
// When we change this to always claim the property is configurable (bug
// 1178639), update the comments in nsOuterWindowProxy::defineProperty
// accordingly.
return js::Wrapper::getOwnPropertyDescriptor(cx, proxy, id, desc);
}
@ -777,14 +780,29 @@ nsOuterWindowProxy::defineProperty(JSContext* cx,
return result.failCantDefineWindowElement();
}
#ifndef RELEASE_BUILD // To be turned on in bug 1178638.
// For now, allow chrome code to define non-configurable properties
// on windows, until we sort out what exactly the addon SDK is
// doing. In the meantime, this still allows us to test web compat
// behavior.
if (false && !desc.configurable() && !nsContentUtils::IsCallerChrome()) {
if (desc.hasConfigurable() && !desc.configurable() &&
!nsContentUtils::IsCallerChrome()) {
return ThrowErrorMessage(cx, MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW);
}
// Note that if hasConfigurable() is false we do NOT want to
// setConfigurable(true). That would make this code:
//
// var x;
// window.x = 5;
//
// fail, because the JS engine ends up converting the assignment into a define
// with !hasConfigurable(), but the var actually declared a non-configurable
// property on our underlying Window object, so the set would fail if we
// forced setConfigurable(true) here. What we want to do instead is change
// getOwnPropertyDescriptor to always claim configurable. See bug 1178639.
#endif
return js::Wrapper::defineProperty(cx, proxy, id, desc, result);
}

View File

@ -790,7 +790,6 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
[test_bug1081686.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s
[test_window_define_nonconfigurable.html]
skip-if = true # bug 1107443 - code for newly-added test was disabled
[test_root_iframe.html]
[test_performance_user_timing.html]
[test_bug1126851.html]

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107443
/** Test for Bug 1107443 **/
try {
Object.defineProperty(window, "nosuchprop", { value: 5 });
Object.defineProperty(window, "nosuchprop", { value: 5, configurable: false });
throw "didn't throw";
} catch (e) {
is(e instanceof TypeError, true,
@ -22,9 +22,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107443
'Window should not have property after an attempt to define it failed');
}
Object.defineProperty(window, "nosuchprop", { value: 7, configurable: true });
Object.defineProperty(window, "nosuchprop", { value: 6 });
var desc = Object.getOwnPropertyDescriptor(window, "nosuchprop");
is(typeof(desc), "object", "Should have a property now");
todo_is(desc.configurable, true, "Property should be configurable");
is(desc.writable, false, "Property should be readonly");
is(desc.value, 6, "Property should have the right value");
Object.defineProperty(window, "nosuchprop2", { value: 7, configurable: true });
desc = Object.getOwnPropertyDescriptor(window, "nosuchprop2");
is(typeof(desc), "object", "Should have a property now");
is(desc.configurable, true, "Property should be configurable");
is(desc.writable, false, "Property should be readonly");
is(desc.value, 7, "Property should have the right value");