diff --git a/js/src/jit-test/tests/proxy/testWrapWithProtoSet.js b/js/src/jit-test/tests/proxy/testWrapWithProtoSet.js new file mode 100644 index 00000000000..91391865710 --- /dev/null +++ b/js/src/jit-test/tests/proxy/testWrapWithProtoSet.js @@ -0,0 +1,8 @@ +// A scripted proxy can delegate a [[Set]] along to a target +// that's a different kind of proxy. + +var target = {}; +var wrapper = wrapWithProto(target, null); +var p = new Proxy(wrapper, {}); +p.prop = 3; +assertEq(target.prop, 3); diff --git a/js/src/proxy/Proxy.cpp b/js/src/proxy/Proxy.cpp index 920d4be334e..67d92da466d 100644 --- a/js/src/proxy/Proxy.cpp +++ b/js/src/proxy/Proxy.cpp @@ -365,18 +365,12 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id } // Ok. Either there was no pre-existing property, or it was a value prop - // that we're going to shadow. Make a property descriptor and define it. - // - // Note that for pre-existing own value properties, we inherit the existing - // attributes, since we're really just changing the value and not trying to - // reconfigure the property. - Rooted newDesc(cx); - if (desc.object() == proxy) - newDesc.setAttributes(desc.attributes()); - else - newDesc.setAttributes(JSPROP_ENUMERATE); - newDesc.value().set(vp); - return handler->defineProperty(cx, receiver, id, &newDesc); + // that we're going to shadow. Either way, define a new own property. + unsigned attrs = + (desc.object() == proxy) + ? JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_PERMANENT + : JSPROP_ENUMERATE; + return JSObject::defineGeneric(cx, receiver, id, vp, nullptr, nullptr, attrs); } bool