testWindowNonConfigurable.cpp (2424B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #include "js/PropertyAndElement.h" // JS_DefineProperty 9 #include "js/Proxy.h" 10 #include "jsapi-tests/tests.h" 11 12 class WindowProxyHandler : public js::ForwardingProxyHandler { 13 public: 14 constexpr WindowProxyHandler() : js::ForwardingProxyHandler(&family) {} 15 16 static const char family; 17 18 virtual bool defineProperty(JSContext* cx, JS::HandleObject proxy, 19 JS::HandleId id, 20 JS::Handle<JS::PropertyDescriptor> desc, 21 JS::ObjectOpResult& result) const override { 22 if (desc.hasConfigurable() && !desc.configurable()) { 23 result.failCantDefineWindowNonConfigurable(); 24 return true; 25 } 26 return ForwardingProxyHandler::defineProperty(cx, proxy, id, desc, result); 27 } 28 }; 29 const char WindowProxyHandler::family = 0; 30 31 static const JSClass windowProxy_class = 32 PROXY_CLASS_DEF("TestWindowProxy", JSCLASS_HAS_RESERVED_SLOTS(1)); 33 static const WindowProxyHandler windowProxy_handler; 34 35 BEGIN_TEST(testWindowNonConfigurable) { 36 JS::RootedObject wrapped(cx, JS_NewObject(cx, nullptr)); 37 CHECK(wrapped); 38 JS::RootedValue wrappedVal(cx, JS::ObjectValue(*wrapped)); 39 js::ProxyOptions options; 40 options.setClass(&windowProxy_class); 41 JS::RootedObject obj(cx, NewProxyObject(cx, &windowProxy_handler, wrappedVal, 42 nullptr, options)); 43 CHECK(obj); 44 CHECK(JS_DefineProperty(cx, global, "windowProxy", obj, 0)); 45 JS::RootedValue v(cx); 46 EVAL( 47 "Object.defineProperty(windowProxy, 'bar', {value: 1, configurable: " 48 "false})", 49 &v); 50 CHECK(v.isNull()); // This is the important bit! 51 EVAL( 52 "Object.defineProperty(windowProxy, 'bar', {value: 1, configurable: " 53 "true})", 54 &v); 55 CHECK(&v.toObject() == obj); 56 EVAL( 57 "Reflect.defineProperty(windowProxy, 'foo', {value: 1, configurable: " 58 "false})", 59 &v); 60 CHECK(v.isFalse()); 61 EVAL( 62 "Reflect.defineProperty(windowProxy, 'foo', {value: 1, configurable: " 63 "true})", 64 &v); 65 CHECK(v.isTrue()); 66 67 return true; 68 } 69 END_TEST(testWindowNonConfigurable)