From 0f251a891ec1deb5ea1438ae5584158e4294152f Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 11 Jun 2014 15:16:06 -0700 Subject: [PATCH] Bug 1020609 - Make configurability check in Xray defineProperty match the spec. r=bz This code is basically emulating the ES semantics with respect to non-configurable properties. Non-configurable value properties can still be writable, in which case their value and writability may be updated. --- js/xpconnect/wrappers/XrayWrapper.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index d024cfa62f48..d217b33a6025 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -2314,8 +2314,22 @@ XrayWrapper::defineProperty(JSContext *cx, HandleObject wrapper, // we often lie (sloppily) about where we found properties and set // desc.object() to |wrapper|. Once we fully fix our Xray prototype semantics, // this should work as intended. - if (existing_desc.object() == wrapper && existing_desc.isPermanent()) - return true; // silently ignore attempt to overwrite native property + if (existing_desc.object() == wrapper && existing_desc.isPermanent()) { + // We have a non-configurable property. See if the caller is trying to + // re-configure it in any way other than making it non-writable. + if (existing_desc.hasGetterOrSetterObject() || desc.hasGetterOrSetterObject() || + existing_desc.isEnumerable() != desc.isEnumerable() || + (existing_desc.isReadonly() && !desc.isReadonly())) + { + // We should technically report non-configurability in strict mode, but + // doing that via JSAPI is a lot of trouble. + return true; + } + if (existing_desc.isReadonly()) { + // Same as the above for non-writability. + return true; + } + } bool defined = false; if (!Traits::singleton.defineProperty(cx, wrapper, id, desc, existing_desc, &defined))